using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using DnsService.Interfaces;
using LocalDnsSdk.Commands;
using NLog;

namespace DnsService.Services
{
    /// <summary>
    /// Sockets管理器实现类
    /// 提供Socket连接的管理功能
    /// 作者：huobing
    /// </summary>
    public class SocketManager : ISocketManager
    {
        private TcpListener? _tcpListener;
        private readonly CancellationTokenSource _cancellationTokenSource;
        private readonly Dictionary<string, SocketClient> _clients;
        private readonly object _clientsLock = new();
        private bool _isDisposed;
        private DateTime _serverStartTime;
        private int _totalConnections;
        private int _totalMessagesReceived;
        private int _totalMessagesSent;
        private readonly List<double> _messageProcessingTimes;
        private readonly int _maxConnections;
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();

        /// <summary>
        /// 服务器启动事件
        /// </summary>
        public event EventHandler<Events.SocketServerEventArgs>? ServerStarted;
        
        /// <summary>
        /// 服务器停止事件
        /// </summary>
        public event EventHandler<Events.SocketServerEventArgs>? ServerStopped;
        
        /// <summary>
        /// 客户端连接事件
        /// </summary>
        public event EventHandler<Events.SocketClientEventArgs>? ClientConnected;
        
        /// <summary>
        /// 客户端断开事件
        /// </summary>
        public event EventHandler<Events.SocketClientEventArgs>? ClientDisconnected;
        
        /// <summary>
        /// 消息接收事件
        /// </summary>
        public event EventHandler<Events.SocketMessageEventArgs>? MessageReceived;

        /// <summary>
        /// 获取管理器是否正在运行
        /// </summary>
        public bool IsRunning { get; private set; }
        
        /// <summary>
        /// 获取当前连接的客户端数量
        /// </summary>
        public int ClientCount 
        { 
            get 
            { 
                lock (_clientsLock)
                {
                    return _clients.Count(c => c.Value.IsConnected);
                }
            } 
        }
        
        /// <summary>
        /// 获取监听端口
        /// </summary>
        public int Port { get; private set; }
        
        /// <summary>
        /// 获取已连接的客户端列表
        /// </summary>
        public IReadOnlyList<Models.SocketClientInfo> ConnectedClients
        {
            get
            {
                lock (_clientsLock)
                {
                    return [.. _clients.Values
                        .Where(c => c.IsConnected)
                        .Select(c => c.GetClientInfo())];
                }
            }
        }

        private CommandExecutor? _commandExecutor;
        private DnsConfigManager? _configManager;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger">日志记录器（可选）</param>
        public SocketManager()
        {
            _cancellationTokenSource = new();
            _clients = [];  
            _messageProcessingTimes = [];
            _totalConnections = 0;
            _totalMessagesReceived = 0;
            _totalMessagesSent = 0;
            _configManager = new DnsConfigManager();
            _maxConnections = _configManager.Config.MaxConnections;
        }

        /// <summary>
        /// 启动Socket服务器
        /// </summary>
        /// <param name="port">监听端口</param>
        /// <returns>是否启动成功</returns>
        public Task<bool> StartAsync(int port)
        {
            if (IsRunning)
            {
                return Task.FromResult(true);
            }

            try
            {
                Port = port;
                _tcpListener = new TcpListener(IPAddress.Any, port);
                _tcpListener.Start();
                IsRunning = true;
                _serverStartTime = DateTime.Now;
                _totalConnections = 0;
                
                // 初始化配置管理器和命令执行器
                if (_configManager == null)
                {
                    _configManager = new DnsConfigManager();
                }
                
                // 初始化命令执行器（Socket模式）
                // 注意：这里假设LocalDnsService已经被创建并可用
                // 如果需要在SocketManager中注入DNS服务，请修改构造函数
                try
                {
                    // 尝试获取当前应用程序中的LocalDnsService实例
                    var dnsService = AppDomain.CurrentDomain.GetAssemblies()
                        .SelectMany(a => a.GetTypes())
                        .Where(t => t.Name == "LocalDnsService" && t.IsClass)
                        .Select(t => Activator.CreateInstance(t))
                        .FirstOrDefault() as IDnsService;
                    
                    if (dnsService != null)
                    {
                        _commandExecutor = new CommandExecutor(
                            dnsService,  // 直接使用IDnsService接口
                            _configManager,
                            CommandExecutor.CommandSource.Socket);
                    }
                }
                catch (Exception ex)
                {
                    // 如果无法创建命令执行器，记录错误但继续启动服务器
                    _logger.Warn("无法初始化命令执行器: {Message}", ex.Message);
                }

                // 触发服务器启动事件
                ServerStarted?.Invoke(this, new Events.SocketServerEventArgs 
            { 
                Port = port, 
                Message = "Socket服务器启动成功" 
            });

                // 开始接受客户端连接
                _ = Task.Run(AcceptClientsAsync, _cancellationTokenSource.Token);

                return Task.FromResult(true);
            }
            catch (Exception ex)
            {
                IsRunning = false;
                throw new Exception($"无法启动Socket服务器: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 停止Socket服务器
        /// </summary>
        public void Stop()
        {
            if (!IsRunning)
            {
                return;
            }

            IsRunning = false;

            // 取消所有操作
            _cancellationTokenSource.Cancel();

            // 停止监听器
            _tcpListener?.Stop();

            // 断开所有客户端连接
            lock (_clientsLock)
            {
                foreach (var client in _clients.Values.ToList())
                {
                    try
                    {
                        client.Disconnect();
                    }
                    catch
                    {
                        // 忽略断开连接时的异常
                    }
                }
                _clients.Clear();
            }
            
            // 清理资源
            _commandExecutor = null;

            // 触发服务器停止事件
            ServerStopped?.Invoke(this, new Events.SocketServerEventArgs 
            { 
                Port = Port, 
                Message = "Socket服务器已停止" 
            });
        }

        /// <summary>
        /// 停止Socket服务器（异步版本）
        /// </summary>
        public async Task StopAsync()
        {
            if (!IsRunning)
            {
                return;
            }

            IsRunning = false;

            // 取消所有操作
            _cancellationTokenSource.Cancel();

            // 停止监听器
            _tcpListener?.Stop();

            // 异步断开所有客户端连接
            var disconnectTasks = new List<Task>();
            lock (_clientsLock)
            {
                foreach (var client in _clients.Values.ToList())
                {
                    disconnectTasks.Add(Task.Run(() =>
                    {
                        try
                        {
                            client.Disconnect();
                        }
                        catch
                        {
                            // 忽略断开连接时的异常
                        }
                    }));
                }
            }

            // 等待所有断开连接任务完成
            await Task.WhenAll(disconnectTasks);

            lock (_clientsLock)
            {
                _clients.Clear();
            }

            // 触发服务器停止事件
            ServerStopped?.Invoke(this, new Events.SocketServerEventArgs 
            { 
                Port = Port, 
                Message = "Socket服务器已停止" 
            });
        }

        /// <summary>
        /// 发送消息到指定客户端
        /// </summary>
        /// <param name="clientId">客户端ID</param>
        /// <param name="message">消息内容</param>
        /// <returns>是否发送成功</returns>
        public async Task<bool> SendMessageAsync(string clientId, string message)
        {
            if (!IsRunning)
            {
                return false;
            }

            SocketClient? client;
            lock (_clientsLock)
            {
                if (!_clients.TryGetValue(clientId, out client) || !client.IsConnected)
                {
                    return false;
                }
            }

            try
            {
                var startTime = DateTime.Now;
                bool success = await client.SendMessageAsync(message);
                var processingTime = (DateTime.Now - startTime).TotalMilliseconds;
                
                if (success)
                {
                    Interlocked.Increment(ref _totalMessagesSent);
                    _messageProcessingTimes.Add(processingTime);
                    
                    // 限制历史记录大小
                    if (_messageProcessingTimes.Count > 1000)
                    {
                        _messageProcessingTimes.RemoveAt(0);
                    }
                }
                
                return success;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 广播消息到所有客户端
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <returns>发送成功的客户端数量</returns>
        public async Task<int> BroadcastMessageAsync(string message)
        {
            if (!IsRunning)
            {
                return 0;
            }

            List<SocketClient> clientsCopy;
            lock (_clientsLock)
            {
                clientsCopy = [.. _clients.Values.Where(c => c.IsConnected)];
            }

            if (clientsCopy.Count == 0)
            {
                return 0;
            }

            var tasks = clientsCopy.Select(client => SendMessageAsync(client.ClientId, message));
            var results = await Task.WhenAll(tasks);
            
            return results.Count(r => r);
        }

        /// <summary>
        /// 断开指定客户端连接
        /// </summary>
        /// <param name="clientId">客户端ID</param>
        /// <returns>是否断开成功</returns>
        public bool DisconnectClient(string clientId)
        {
            SocketClient? client;
            lock (_clientsLock)
            {
                if (!_clients.TryGetValue(clientId, out client))
                {
                    return false;
                }
            }

            try
            {
                client.Disconnect();
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 获取客户端连接统计信息
        /// </summary>
        /// <returns>连接统计信息</returns>
        public SocketConnectionStatistics GetConnectionStatistics()
        {
            return new SocketConnectionStatistics
            {
                TotalConnections = _totalConnections,
                CurrentConnections = ClientCount,
                TotalMessagesReceived = _totalMessagesReceived,
                TotalMessagesSent = _totalMessagesSent,
                ServerStartTime = _serverStartTime
            };
        }

        /// <summary>
        /// 获取服务器状态信息
        /// </summary>
        /// <returns>服务器状态信息</returns>
        public SocketServerStatus GetServerStatus()
        {
            var metrics = new SocketPerformanceMetrics
            {
                AverageMessageProcessingTimeMs = _messageProcessingTimes.Count > 0 ? 
                    _messageProcessingTimes.Average() : 0,
                MessageProcessingSuccessRate = _totalMessagesSent > 0 ? 
                    (double)_totalMessagesSent / (_totalMessagesSent + _messageProcessingTimes.Count(t => t > 1000)) : 1.0,
                ConnectionSuccessRate = _totalConnections > 0 ? 
                    (double)ClientCount / _totalConnections : 1.0,
                MemoryUsageMB = GC.GetTotalMemory(false) / 1024.0 / 1024.0
            };

            return new SocketServerStatus
            {
                IsRunning = IsRunning,
                Port = Port,
                CurrentConnections = ClientCount,
                MaxConnections = _maxConnections, // 可配置的最大连接数
                StartTime = IsRunning ? _serverStartTime : null,
                PerformanceMetrics = metrics
            };
        }

        /// <summary>
        /// 接受客户端连接
        /// </summary>
        private async Task AcceptClientsAsync()
        {
            try
            {
                while (!_cancellationTokenSource.Token.IsCancellationRequested && _tcpListener != null)
                {
                    TcpClient tcpClient = await _tcpListener.AcceptTcpClientAsync();
                    
                    // 最大连接数限制
                    if (ClientCount >= _maxConnections)
                    {
                        try { tcpClient.Close(); } catch { }
                        continue;
                    }
                    
                    var client = new SocketClient(tcpClient);
                    
                    lock (_clientsLock)
                    {
                        _clients[client.ClientId] = client;
                    }

                    Interlocked.Increment(ref _totalConnections);

                    // 触发客户端连接事件
                    ClientConnected?.Invoke(this, new Events.SocketClientEventArgs 
                    { 
                        ClientInfo = client.GetClientInfo() 
                    });

                    // 处理客户端消息
                    _ = Task.Run(() => HandleClientAsync(client), _cancellationTokenSource.Token);
                }
            }
            catch (OperationCanceledException)
            {
                // 正常取消操作，不处理
            }
            catch (Exception ex)
            {
                // 记录错误但不抛出异常
                _logger.Error($"接受客户端连接时发生错误: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 处理客户端消息
        /// </summary>
        /// <param name="client">客户端</param>
        private async Task HandleClientAsync(SocketClient client)
        {
            try
            {
                while (!_cancellationTokenSource.Token.IsCancellationRequested && client.IsConnected)
                {
                    string? message = await client.ReceiveMessageAsync(_cancellationTokenSource.Token);
                    
                    if (string.IsNullOrEmpty(message))
                    {
                        // 客户端断开连接
                        break;
                    }

                    Interlocked.Increment(ref _totalMessagesReceived);

                    // 使用命令执行器处理消息
                    string response = string.Empty;
                    if (_commandExecutor != null)
                    {
                        try
                        {
                            bool success = _commandExecutor.Execute(message, out response);
                            
                            // 如果命令执行成功且有响应，发送回客户端
                            if (success && !string.IsNullOrEmpty(response))
                            {
                                await client.SendMessageAsync(response);
                            }
                        }
                        catch (Exception ex)
                        {
                            // 命令执行出错，发送错误消息给客户端
                            response = $"错误: {ex.Message}";
                            await client.SendMessageAsync(response);
                        }
                    }
                    else
                    {
                        // 命令执行器未初始化，返回错误消息
                        response = "错误: 命令执行器未初始化";
                        await client.SendMessageAsync(response);
                    }

                    // 触发消息接收事件
                    if (MessageReceived != null)
                    {
                        var handler = MessageReceived;
                        var args = new Events.SocketMessageEventArgs
                        {
                            ClientInfo = client.GetClientInfo(),
                            Message = message,
                            MessageSize = Encoding.UTF8.GetByteCount(message)
                        };
                        
                        // 异步处理消息，避免阻塞接收循环
                        _ = Task.Run(() => handler(this, args));
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // 正常取消操作，不处理
            }
            catch (Exception ex)
            {
                // 记录错误，但不中断主循环
                _logger.Error($"处理客户端消息时发生错误: {ex.Message}", ex);
            }
            finally
            {
                // 清理客户端连接
                RemoveClient(client.ClientId);
            }
        }

        /// <summary>
        /// 移除客户端
        /// </summary>
        /// <param name="clientId">客户端ID</param>
        private void RemoveClient(string clientId)
        {
            SocketClient? client;
            lock (_clientsLock)
            {
                if (_clients.TryGetValue(clientId, out client))
                {
                    _clients.Remove(clientId);
                }
            }

            if (client != null)
            {
                try
                {
                    client.Disconnect();
                }
                catch
                {
                    // 忽略断开连接时的异常
                }

                // 触发客户端断开事件
                ClientDisconnected?.Invoke(this, new Events.SocketClientEventArgs 
                { 
                    ClientInfo = client.GetClientInfo() 
                });
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (_isDisposed)
            {
                return;
            }

            _isDisposed = true;
            Stop();
            _cancellationTokenSource.Dispose();
        }
    }

    /// <summary>
    /// Socket客户端封装类
    /// 作者：huobing
    /// </summary>
    internal class SocketClient : IDisposable
    {
        private readonly TcpClient _tcpClient;
        private readonly NetworkStream _stream;
        private readonly byte[] _buffer;
        private bool _isDisposed;
        private readonly DateTime _connectedTime;
        private DateTime _lastActivityTime;
        private int _messagesReceived;
        private int _messagesSent;

        /// <summary>
        /// 客户端ID
        /// </summary>
        public string ClientId { get; }

        /// <summary>
        /// 是否已连接
        /// </summary>
        public bool IsConnected => _tcpClient.Connected && !_isDisposed;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="tcpClient">TCP客户端</param>
        public SocketClient(TcpClient tcpClient)
        {
            _tcpClient = tcpClient;
            _stream = tcpClient.GetStream();
            _buffer = new byte[4096];
            _connectedTime = DateTime.Now;
            _lastActivityTime = DateTime.Now;
            _messagesReceived = 0;
            _messagesSent = 0;
            
            // 生成客户端ID
            ClientId = $"{((IPEndPoint)_tcpClient.Client.RemoteEndPoint!).Address}:{((IPEndPoint)_tcpClient.Client.RemoteEndPoint!).Port}";
        }

        /// <summary>
        /// 发送消息（确保以换行符结尾）
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <returns>是否发送成功</returns>
        public async Task<bool> SendMessageAsync(string message)
        {
            if (!IsConnected)
            {
                return false;
            }

            try
            {
                // 确保消息以换行符结尾，符合文本命令格式
                string formattedMessage = message.EndsWith("\n") ? message : message + "\n";
                byte[] data = Encoding.UTF8.GetBytes(formattedMessage);
                await _stream.WriteAsync(data, 0, data.Length);
                await _stream.FlushAsync();
                
                _lastActivityTime = DateTime.Now;
                _messagesSent++;
                
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 接收消息（按行读取）
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>接收到的消息行</returns>
        public async Task<string?> ReceiveMessageAsync(CancellationToken cancellationToken = default)
        {
            if (!IsConnected)
            {
                return null;
            }

            try
            {
                StringBuilder lineBuilder = new();
                bool lineComplete = false;
                
                // 连续读取，直到遇到换行符或连接关闭
                while (!lineComplete && !cancellationToken.IsCancellationRequested)
                {
                    int bytesRead = await _stream.ReadAsync(_buffer, 0, _buffer.Length, cancellationToken);
                    
                    if (bytesRead <= 0)
                    {
                        // 客户端断开或没有更多数据
                        return lineBuilder.Length > 0 ? lineBuilder.ToString() : null;
                    }

                    // 查找当前块中的换行符
                    for (int i = 0; i < bytesRead; i++)
                    {
                        if (_buffer[i] == (byte) '\n')
                        {
                            // 行读取完成，追加换行符之前的内容
                            lineComplete = true;
                            if (i > 0)
                            {
                                lineBuilder.Append(Encoding.UTF8.GetString(_buffer, 0, i));
                            }
                            break;
                        }
                    }

                    // 未找到换行符，追加整个块
                    if (!lineComplete)
                    {
                        lineBuilder.Append(Encoding.UTF8.GetString(_buffer, 0, bytesRead));
                    }
                }

                // 生成消息字符串，去掉行尾CR以及可能的BOM
                string message = lineBuilder.ToString().TrimEnd('\r');
                if (!string.IsNullOrEmpty(message) && message[0] == '\uFEFF')
                {
                    message = message.Substring(1);
                }
                
                _lastActivityTime = DateTime.Now;
                _messagesReceived++;
                
                return message;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnect()
        {
            if (!IsConnected)
            {
                return;
            }

            try
            {
                _stream.Close();
                _tcpClient.Close();
            }
            catch
            {
                // 忽略断开连接时的异常
            }
        }

        /// <summary>
        /// 获取客户端信息
        /// </summary>
        /// <returns>客户端信息</returns>
        public Models.SocketClientInfo GetClientInfo()
        {
            return new Models.SocketClientInfo
            {
                ClientId = ClientId,
                IPAddress = ((IPEndPoint)_tcpClient.Client.RemoteEndPoint!).Address.ToString(),
                ConnectedTime = _connectedTime,
                LastActivityTime = _lastActivityTime,
                MessagesReceived = _messagesReceived,
                MessagesSent = _messagesSent,
                IsOnline = IsConnected
            };
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (_isDisposed)
            {
                return;
            }

            _isDisposed = true;
            Disconnect();
        }
    }
}